#!/bin/bash

#Descripción: Este script procesa y los archivos de prestamos por pais y los normaliza
#   agregando los registros al archivo de prestamos por pais correspondiente.
#Pasos:
#   1- Chequea si existen archivos a procesar
#   2- Chequea si el archivo ya fue procesado, lo rechaza si ya lo fue
#   3- Extrae los campos necesarios del archivo segun las tablas T1 y T2
#   4- Realiza el calculo del monto restante del prestamo
#   5- Si el monto restane es mayor a cero inserta el registro en el archivo de prestamos por pais
#   6- Almacena el archivo procesado
#
#Opciones y parametros definidos por el desarrollador: Ninguno
#
#Hipotesis: Si el entorno fue inicializado, existen todos los directorios y variables de ambiente
#
#==============================================================================

#Para poder hacer un poco mas generico el script
APPROOT=$(pwd)

#Estas son las variables de ambiente o que fueron levantadas del archivo de config.
#ACEPDIR="${APPROOT}/grupo06/aceptados"
#CONFDIR="${APPROOT}/grupo06/conf"
#PROCDIR="${APPROOT}/grupo06/procesados"
#RECHDIR="${APPROOT}/grupo06/rechazados"


#=goToMain=====================================================================
#==================================Funciones===================================

#Chequea si el archivo ya fue procesado
fue_procesado()
{
	[ -e "${PROCDIR}/${1}" ]
	return $?
}


#Extrae el sistema y el pais del nombre del archivo
extraer_pais_sistema()
{
    PAIS=$(echo "${1}" | cut -d'-' -f1)
    SISTEMA=$(echo "${1}" | cut -d'-' -f2)
}


#Extrae los separadores de campos y decimales de la tabla T1
extraer_separadores()
{
    local TAB_1="${CONFDIR}/T1.tab"

	#El segundo "cut" es porque los archivos de tablas tiene fines de linea de windows
    SEPARADOR_CAMPOS=$(grep "^${1}-${2}-.-." "${TAB_1}" | cut -d'-' -f3 | cut -b1)
    SEPARADOR_DECIMAL=$(grep "^${1}-${2}-.-." "${TAB_1}" | cut -d'-' -f4 | cut -b1)
}


obtener_valor_campo() # $linea $T2_DATA $campo default
{
    local POS=$(echo "$2" | grep "\-$3\-" | cut -d'-' -f4 | tr -c -d '[:graph:]')
    FORMAT=$(echo "$2" | grep "\-$3\-" | cut -d'-' -f5 | tr -c -d '[:graph:]')
    if [ -z "$POS" ] ; then
        eval "$3=\$4"
    else
        eval "$3"='$(echo "$1" | cut -d"${SEPARADOR_CAMPOS}" -f${POS})'
        if [ -z ${!3} ] ; then
            eval "$3=\$4"
        fi
    fi
    #cuando resuelve eval, reemplaza las variables y elimina un nivel de comillas
}

#Carga los valores formateados en las variables globales
obtener_valores()   #"${linea}" "${T2_DATA}"
{
	for campo in MT_DEB MT_PRES MT_INDE MT_IMPAGO MT_INNODE
	do
	    local FORMAT=""
	    obtener_valor_campo "$1" "$2" "$campo" "0"
	    validar_decimal "${FORMAT}" "${!campo}"
	    if [ $? -ne 0 ]
	    then
	    	return 1
	    fi
	done
	return 0
}

#Extreae los datos necesarios
obtener_datos() #"${linea}" "${T2_DATA}"
{
    local FORMAT=""
    obtener_valor_campo "$1" "$2" "CTB_FE" "01/01/2001"
    obtener_fecha_valida "${FORMAT}" "${CTB_FE}"
    if [ $? -ne 0 ]
    then
    	return 1
    fi
    
    for campo in PRES_ID PRES_CLI CTB_ESTADO PRES_CLI_ID
	do
	    obtener_valor_campo "$1" "$2" "$campo" " "
	    validar_alfanumerico "${FORMAT}" "${!campo}"
	    if [ $? -ne 0 ]
	    then
	    	return 1
	    fi
	done
    return 0
}

obtener_fecha_valida () # "${FORMAT}" "${CTB_FE}"
{
	if [ "${1}" == "ddmmyy8." -o "${1}" == "yymmdd8." ]
	then
		if [ ! -z "$(echo "$2" | grep "^[0-9]\{8\}$")" ]
		then
			if [ "${1}" == "ddmmyy8." ]
			then
				CTB_DIA=$(echo "${2}" | cut -c 1-2)
				CTB_MES=$(echo "${2}" | cut -c 3-4)
				CTB_ANIO=$(echo "${2}" | cut -c 5-8)
				validar_fecha "${CTB_DIA}" "${CTB_MES}" "${CTB_ANIO}"
				return $?
			else
				CTB_ANIO=$(echo "${2}" | cut -c 1-4)	
				CTB_MES=$(echo "${2}" | cut -c 5-6)
				CTB_DIA=$(echo "${2}" | cut -c 7-8)
				validar_fecha "${CTB_DIA}" "${CTB_MES}" "${CTB_ANIO}"
				return $?
			fi
		else
#			echo "ERROR: Campo CTB_FE '$2' no contiene 8 numeros"
			GlogY.sh "Interprete" "E" "Campo CTB_FE '${2}' no contiene 8 numeros"
			return 1
		fi
	
	elif [ "${1}" == "ddmmyy10." -o "${1}" == "yymmdd10." ]
	then
		if [ "${1}" == "ddmmyy10." ]
		then
			if [ ! -z "$(echo "$2" | grep "^[0-9]\{2\}.[0-9]\{2\}.[0-9]\{4\}$")" ]
			then		
				CTB_DIA=$(echo ${2} | cut -c 1-2)
				CTB_MES=$(echo ${2} | cut -c 4-5)
				CTB_ANIO=$(echo ${2} | cut -c 7-10)
				validar_fecha "${CTB_DIA}" "${CTB_MES}" "${CTB_ANIO}"
				return $?
			else
#				echo "ERROR: Campo CTB_FE '$2' no contiene 2 numeros | 2 numeros | 4 numeros"
				GlogY.sh "Interprete" "E" "Campo CTB_FE '${2}' no contiene 2 numeros | 2 numeros | 4 numeros"
				return 1
			fi
	
		else
			if [ ! -z "$(echo "$2" | grep "^[0-9]\{4\}.[0-9]\{2\}.[0-9]\{2\}$")" ]
			then
				CTB_ANIO=$(echo ${2} | cut -c 1-4)	
				CTB_MES=$(echo ${2} | cut -c 6-7)
				CTB_DIA=$(echo ${2} | cut -c 9-10)
				validar_fecha "${CTB_DIA}" "${CTB_MES}" "${CTB_ANIO}"
				return $?
			else
#				echo "ERROR: Campo CTB_FE '$2' no contiene 4 numeros | 2 numeros | 2 numeros"
				GlogY.sh "Interprete" "E" "Campo CTB_FE ${2} no contiene 4 numeros | 2 numeros | 2 numeros"
				return 1
			fi
		fi
	else
#		echo "ERROR: Formato de fecha invalido en '$1'"
		GlogY.sh "Interprete" "E" "Formato de fecha invalido en ${1}"
	return 1
	fi
}

validar_fecha () # "${CTB_DIA}" "${CTB_MES}" "${CTB_ANIO}"
{
	# Verifico que la fecha sea valida, es decir, 28,30,31 segun mes y 29/02 segun anio bisiesto
	if ! date -d "${2}/${1}/${3}" '+%D' > /dev/null
	then
#		echo "ERROR: Fecha Invalida."
		GlogY.sh "Interprete" "E" "Fecha Invalida"
		return 1
	fi
	
	if [ "${3}" -le 2000 ]
	then
#		echo "ERROR: El CTB_ANIO es menor a 2000"
		GlogY.sh "Interprete" "E" "El CTB_ANIO es menor a 2000"
		return 1
	fi

	[ "$(date -d "$2/$1/$3" +"%s")" -lt  "$(date +"%s")" ]
	return $?
}

validar_alfanumerico () # "${FORMAT}" "${DATO}"
{
	if [ -z "$1" -o -z "$2" ]
	then
		return 0
	fi

	if [ -z "$(echo "$1" | grep '^\$[[:digit:]]*\.$')" ]
	then
#		echo "ERROR: Formato de campo alfanumerico '$1' invalido"
		GlogY.sh "Interprete" "E" "Formato de campo alfanumerico '${1}' invalido"
		return 1
	fi

	# Verifico que el dato tenga menos longitud que la que indica FORMAT $<longitud> y que sean alfanumericos
	local LONG="$(echo "$1" | sed "s-.\(.*\).-\1-g")"
	if [ $((LONG + 1)) -lt "$(echo "$2" | wc -m)" ]
	then
		GlogY.sh "Interprete" "E" "Campo alfanumerico demasiado largo ${2}, se esperaba ${LONG}"
#		echo "ERROR: Campo alfanumerico demasiado largo: '$2'"
#		echo "       La long esperada es de '$LONG'"
		return 1
	else
		return 0		
	fi
}

validar_decimal() # $formato $numero
{
	# Verifica que cumpla longitudes y que sean digitos
	# FALTA: CAMBIAR EL SEPARADOR DECIMAL POR UN . PARA PODER REALIZAR LAS OPERACIONES
	local formato=${1%%[[:digit:]]*}

	if [ "$formato" != "commax" ]
	then 
#		echo "Error: Formato de campo invalido '$1'"
		GlogY.sh "Interprete" "E" "Formato de campo invalido '${1}'"
		return 1;
	fi

        #obtengo la longitud maxima para el entero y decimal
	local longEntMax=$(echo ${1##*[[:alpha:]]} | cut -d "." -f 1)
	local longDecMax=$(echo ${1##*[[:alpha:]]} | cut -d "." -f 2)
	
	#verifico que segundo parametro no este vacio
	local patronEnt="[[:digit:]]\{1,$longEntMax\}"
	local patronDec="[[:digit:]]\{1,$longDecMax\}"
	local patron="^$patronEnt\(\\$SEPARADOR_DECIMAL$patronDec\)\?$"
	if [ -z "$(echo "$2" | grep "$patron")" ]
	then
#		echo "Error: Campo invalido '$2' para formato '$1', separador '$SEPARADOR_DECIMAL'"
		GlogY.sh "Interprete" "E" "Campo invalido '${2}' para formato '${1}', separador '${SEPARADOR_DECIMAL}'"
		return 1
	else
		return 0
	fi
}


#=goToMain=====================================================================
#================================Empieza el script=============================


# verifico el entorno
if [ "${INICIO_OK}" != "grupo06" ]
then
    echo "ERROR: El ambiente no esta correctamente inicializado."
    echo "       Por favor ejecute InicioY.sh"
    exit 1
fi


### Chequea si existe otra instancia corriendo, si esta sale ###
#==============================================================================
if ! bloquear_pid.sh "Interprete" ; then
	exit 1
fi
trap "desbloquear_pid.sh 'Interprete'" EXIT
#==============================================================================
### Fin de chequeo ###


# Chequea que existan archivos en el directorio de aceptados (entrada)
if [ -z "$(ls "${ACEPDIR}"/)" ]
then
    GlogY.sh "Interprete" "I" "No existen archivos a procesar"
    exit 0
else
    #Muestra la cantidad de archivos (Esto incluye subDirs y links)
    GlogY.sh "Interprete" "I" "Inicio del interprete, existen $(ls "${ACEPDIR}" | wc -w) archivos para procesar"
fi

#Lleva la cuenta de los registros procesados
CANT_REGS_IN=0
CANT_REGS_OUT=0

#Lee todos los archivos del directorio de aceptados
for arch in "${ACEPDIR}"/*
do
    #Chequea que no se trabaje con directorios
    if [ -d "${arch}" ]
    then
        continue
    fi

    #Valida que el archivo no este duplicado
    fue_procesado "${arch##*/}"
    if [ $? -eq 0 ]	# "$?" es el resultado de la funcion que recien fue llamada
    then
        GlogY.sh "Interprete" "I" "DUPLICADO: ${arch##*/}"
        MoverY.sh "${arch}" "${RECHDIR}" "Interprete"
        continue
    fi

    #Extrae el sistema y pais del nombre del archivo
    PAIS=""
    SISTEMA=""
    extraer_pais_sistema "${arch##*/}"

    #Extrae los separadores para el tipo de archivo de la tabla de separadores T1
    SEPARADOR_CAMPOS=""
    SEPARADOR_DECIMAL=""
    extraer_separadores "${PAIS}" "${SISTEMA}"

    #Valida que existan los separadores para el par "PAIS-SISTEMA"
    if [ -z "${SEPARADOR_CAMPOS}" -o -z "${SEPARADOR_DECIMAL}" ]
    then
        GlogY.sh "Interprete" "SE" "No existen los separadores para el par ${PAIS}-${SISTEMA} de ${arch##*/}"
        exit 1
    fi

    #Recupera los datos de la tabla de campos T2
    T2_DATA=$(grep "^${PAIS}-${SISTEMA}" "${CONFDIR}/T2.tab")
	if [ -z "${T2_DATA}" ]
	then
		GlogY.sh "Interprete" "E" "No existe datos de campos para el par ${PAIS}-${SISTEMA} de ${arch##*/}"
		continue;
	fi

    #En caso de rechazar lineas
    LINEAS_RECHAZADAS_FN=$(mktemp)
    LINEAS_RECHAZADAS=0

    #Procesa una linea a la vez del archivo
    OLD_IFS=${IFS}
    IFS=$'\r\n'
    for linea in $(<${arch})
    do
        #Aumenta en 1 el contador de registros de entrada
        CANT_REGS_IN=$[ ${CANT_REGS_IN} +1 ]

        #Extrae los campos de valores necesarios
        MT_DEB="0"
        MT_PRES="0"
        MT_INDE="0"
        MT_IMPAGO="0"
        MT_INNODE="0"
        if ! obtener_valores "${linea}" "${T2_DATA}"
	then
		echo "$linea" >> "$LINEAS_RECHAZADAS_FN"
		LINEAS_RECHAZADAS=$((LINEAS_RECHAZADAS+1))
		GlogY.sh "Interprete" "I" "Se rechazo una linea del archivo \"${arch##*/}\""
		continue
	fi

	#Se cambian los separadores decimales para poder hacer las cuentas
	if [ "$SEPARADOR_DECIMAL" != "." ]
	then
	        MT_DEB="$(echo "$MT_DEB" | tr "$SEPARADOR_DECIMAL" ".")"
	        MT_PRES="$(echo "$MT_PRES" | tr "$SEPARADOR_DECIMAL" ".")"
	        MT_INDE="$(echo "$MT_INDE" | tr "$SEPARADOR_DECIMAL" ".")"
	        MT_IMPAGO="$(echo "$MT_IMPAGO" | tr "$SEPARADOR_DECIMAL" ".")"
	        MT_INNODE="$(echo "$MT_INNODE" | tr "$SEPARADOR_DECIMAL" ".")"
	fi

        #Calcula el monto restante
        MT_REST=$(echo "${MT_PRES:-0} + ${MT_IMPAGO:-0} + ${MT_INDE:-0} + ${MT_INNODE:-0} - ${MT_DEB:-0}" | bc)

        #Solo se graba el registro si MT_REST es mayor o igual a cero
        if [ 0 -ne "$(echo "${MT_REST} < 0" | bc)" ]
        then
		GlogY.sh "Interprete" "I" "El monto de la linea:  \"${linea}\" es menor o igual a cero"
            continue   #Sigue con la proxima linea
        fi

        INS_FE=$(date +%d/%m/%Y)
        #Los campos de datos necesarios son:
        CTB_DIA=""
        CTB_MES=""
        CTB_ANIO=""
        PRES_ID=""
        PRES_CLI=""
        CTB_ESTADO=""
        PRES_CLI_ID=""
        if ! obtener_datos "${linea}" "${T2_DATA}"
        then
		echo "$linea" >> "$LINEAS_RECHAZADAS_FN"
		LINEAS_RECHAZADAS=$((LINEAS_RECHAZADAS+1))
		GlogY.sh "Interprete" "I" "La linea:  \"${linea}\" contiene campos invalidos"
        	continue
        fi

        #Adapto el formato de prestamos.<pais>
        for variable in MT_DEB MT_PRES MT_INDE MT_IMPAGO MT_INNODE MT_REST
        do
            eval "$variable"='$(echo "${!variable}" | tr '.' ',')'
	    if [ "$(echo "${!variable}" | cut -c1)" = ',' ]
	    then
	        eval "$variable"='0${!variable}'
	    fi
        done

        #Crea el nuevo registro
        REGISTRO="${SISTEMA};${CTB_ANIO};${CTB_MES};${CTB_DIA};${CTB_ESTADO};${PRES_ID};${MT_PRES:-0};${MT_IMPAGO:-0};${MT_INDE:-0};${MT_INNODE:-0};${MT_DEB:-0};${MT_REST:-0};${PRES_CLI_ID};${PRES_CLI};${INS_FE};${USER}"

        #Si no existe el archivo lo crea
        ARCHIVO_PRESTAMOS="${PROCDIR}/PRESTAMOS.${PAIS}" 
        if [ ! -e "${ARCHIVO_PRESTAMOS}" ]
        then
            touch "${ARCHIVO_PRESTAMOS}" 
		GlogY.sh "Interprete" "I" "Creando el archivo de prestamos por pais: ${ARCHIVO_PRESTAMOS}"
        fi

        #Guarda el nuevo registro
        echo "${REGISTRO}" >> "${ARCHIVO_PRESTAMOS}"

        #Aumenta en 1 el contador de registros de salida
        CANT_REGS_OUT=$[ ${CANT_REGS_OUT} +1 ]
    done
    IFS=${OLD_IFS}

    #Mueve el archivo procesado
    MoverY.sh "${arch}" "${PROCDIR}" "Interprete"

    #En caso de haber rechazado lineas
    if [ "$LINEAS_RECHAZADAS" -gt 0 ]
    then
    	mv "$LINEAS_RECHAZADAS_FN" "$arch"
	MoverY.sh "$arch" "$RECHDIR" "Interprete"
    else
    	rm "$LINEAS_RECHAZADAS_FN"
    fi
done

GlogY.sh "Interprete" "I" "Registros de entrada: ${CANT_REGS_IN}, Registros de salida: ${CANT_REGS_OUT}."
GlogY.sh "Interprete" "I" "Fin de interprete"

exit 0

